<!doctype html>

<html>

<head>
  <meta http-equiv="Content-type" content="text/html; charset=utf-8" />

  <link rel="stylesheet" type="text/css" href="../../style/style.css" media="screen" />
  <link rel="stylesheet" type="text/css" href="../../style/slider/default/style.css" media="screen" />
  <link rel="stylesheet" type="text/css" href="../demo.css" media="screen" />

  <title>Basis Demos: Data indexes</title>

  <style type="text/css" id="demo-css">
    HTML,
    BODY
    {
      font-size: small;
      font-family: Tahoma, Verdana, Arial, sans-serif;
    }

    #demo-container
    {
      font-family: Consolas;
    }

    .barWrapper
    {
      position: relative;
      text-align: right;
    }
    .bar
    {
      position: absolute;
      height: 100%;
      background: rgba(128,200,128,.5);
      right: 0;
    }
    .label
    {
      position: relative;
    }

    .diff
    {
      color: red;
    }

    .Basis-Table
    {
      margin-right: 2ex;
      float: left;
    }
    #RecordPanel
    {
      width: 250px;
      float: left;
    }
    .Basis-ButtonPanel
    {
      padding-bottom: .5em;
    }
  </style>
  <!--[if lt IE 7]>
  <style type="text/css">
    BODY
    {
      font-size: x-small;
    }
  </style>
  <![endif]-->

  <!--[if IE 7]>
  <![endif]-->


  <script type="text/javascript" src="../../basis-all.js"></script>

  <script type="text/javascript" src="../seedrandom.js"></script>
  <script type="text/javascript" src="../demo.js"></script>
</head>

<body>
  <h1>Basis Demos: Data indexes</h1>
  
  <p id="demo-summary">
    ..
  </p>
  <div id="demo-description">
    ..
  </div>

  <div id="demo-container">
  </div>

  <script type="text/javascript" id="demo-javascript">

    basis.require('basis.dom');
    basis.require('basis.cssom');
    basis.require('basis.data');
    basis.require('basis.dom.wrapper');
    basis.require('basis.data.index');
    basis.require('basis.ui.button');
    basis.require('basis.ui.table');
    basis.require('basis.ui.slider');

    // import names
    var DOM = basis.dom;
    var nsData = basis.data;
    var nsWrapper = basis.dom.wrapper;
    var nsDataIndex = basis.data.index;
    var cssom = basis.cssom;

    var getter = Function.getter;
    var ButtonPanel = basis.ui.button.ButtonPanel;
    var Table = basis.ui.table.Table;
    var Slider = basis.ui.slider.Slider;

    var UINode = basis.ui.Node;
    var UIContainer = basis.ui.Container;

    Math.seedrandom("basis");

    var createDataItem = (function(){
      var seed = 0;

      return function(){
        seed++;
        return new basis.data.Object({
          data: {
            id: seed,
            title: 'item' + seed,
            value: parseInt(50 * Math.random()),
            total: parseInt(150 * Math.random())
          }
        });
      }
    })();

    var dataset = new basis.data.Dataset({
      items: Array.create(15, createDataItem)
    });

    var indexMap = new nsDataIndex.IndexMap({
      source: dataset,
      indexes: {
        valueMax: nsDataIndex.max('data.value'),
        totalMax: nsDataIndex.max('data.total'),
        totalMin: nsDataIndex.min('data.total'),
        totalSum: nsDataIndex.sum('data.total')
      },
      calcs: {
        percentOfValueMax: function(data, indexes){
          return data.value / indexes.valueMax;
        },
        percentOfTotalMax: function(data, indexes){
          return (data.total - indexes.totalMin) / (indexes.totalMax - indexes.totalMin);
        },
        percentOfTotalSum: function(data, indexes){
          return data.total / indexes.totalSum;
        }
      }
    });

    new ButtonPanel({
      container: DOM.get('demo-container'),
      childNodes: [
        {
          caption: 'add',
          click: function(){
            dataset.add([createDataItem()]);
          }
        },
        {
          caption: 'add 5',
          click: function(){
            dataset.add(Array.create(5, createDataItem));
          }
        },
        {
          caption: 'remove',
          click: function(){
            if (table.firstChild)
              dataset.remove([table.firstChild.root]);
          }
        },
        {
          caption: 'stress test #1',
          click: function(){
            var items = dataset.getItems();
            var t = new Date();
            var i;

            indexMap.lock();
            for (i = 0; i < 1000; i++)
            {
              var item = items[parseInt(8461 * i) % items.length];
              item.update({
                value: (item.data.value + i) % 50,
                total: (item.data.total + i) % 150
              });
            }
            indexMap.unlock();

            console.log('stress test time', new Date - t);
          }
        }
      ]
    });

    var count = 0;
    var table = new Table({
      container: DOM.get('demo-container'),
      dataSource: dataset, //new basis.data.dataset.Subset({ source: dataset, rule: function(d){ return d.data.id < 50 } }),
      structure: [
        {
          header: '#',
          body: '{id}',
          footer: function(){
            return [
              'min/max: ',
              dataset.getIndex(basis.data.index.min('data.value')).addLink(basis.dom.createText()),
              '/',
              dataset.getIndex(basis.data.index.max('data.value')).addLink(basis.dom.createText())
            ];
          }
        },
        {
          sorting: 'data.title',
          header: 'Title',
          body: '{title}'
        },
        {
          sorting: Function.getter('data.value', Number),
          cssClassName: 'right',
          header: 'Value',
          body: '<div class="barWrapper"><div{percentOfValueMax} class="bar"/><span class="label">{value}</span></div>',
          footer: function(){
            return dataset.getIndex(basis.data.index.count(Function.$true)).addLink(basis.dom.createText());
          }
        },
        {
          sorting: Function.getter('data.total', Number),
          cssClassName: 'right',
          header: 'Total',
          body: '<div class="barWrapper"><div{percentOfTotalMax} class="bar"/><span class="label">{total}</span></div>',
          footer: function(){
            return dataset.getIndex(basis.data.index.sum('data.total')).addLink(basis.dom.createText());
          }
        },
        {
          header: 'Total, %',
          cssClassName: 'right',
          body: '{percentOfTotalSum}',
          footer: function(){
            return indexMap.getIndex(basis.data.index.avg('data.percentOfTotalMax * 100')).addLink(basis.dom.createText(), null, '{0:.2}%');
          }
        }
      ],

      childClass: {
        templateUpdate: function(tmpl, eventName, delta){
          if (delta)
            for (var key in delta)
              tmpl[key].nodeValue = this.data[key];
          else
            for (var key in this.data)
              if (key in tmpl)
                tmpl[key].nodeValue = this.data[key];
        },
        satelliteConfig: {
          indexes: {
            hook: { rootChanged: true },
            delegate: function(owner){
              return indexMap.getMember(owner.root);
            },
            instanceOf: nsData.Object.subclass({
              active: true,
              event_update: function(delta){
                //console.log(count++, delta);
                nsData.Object.prototype.event_update.call(this, delta);

                var tmpl = this.owner.tmpl;
                tmpl.percentOfTotalSum.nodeValue = '{0:.2}%'.format(100 * this.data.percentOfTotalSum);
                tmpl.percentOfTotalMax.style.width = '{0:.2}%'.format(100 * this.data.percentOfTotalMax);
                tmpl.percentOfValueMax.style.width = '{0:.2}%'.format(100 * this.data.percentOfValueMax);
              }
            })
          }
        }
      },
      selection: {
        handler: {
          datasetChanged: function(){
            recordPanel.setDelegate(this.pick());
          }
        }
      }
    });

    var recordPanel = new UIContainer({
      container: DOM.get('demo-container'),
      id: 'RecordPanel',
      handler: {
        delegateChanged: function(){
          cssom.display(this.element, !!this.delegate);
        }
      },
      childNodes: [
        new Slider({
          autoDelegate: basis.dom.wrapper.DELEGATE.PARENT,
          min: 0,
          max: 50,
          marks: 10,
          handler: {
            update: function(){
              if ('value' in this.data)
                this.setValue(this.data.value);
            },
            change: function(){
              this.update({ value: this.value });
            }
          }
        }),
        new Slider({
          autoDelegate: basis.dom.wrapper.DELEGATE.PARENT,
          min: 0,
          max: 150,
          marks: 10,
          handler: {
            update: function(){
              if ('total' in this.data)
                this.setValue(this.data.total);
            },
            change: function(){
              this.update({ total: this.value });
            }
          }
        })
      ]
    });
    cssom.hide(recordPanel.element);


    
  </script>
</body>

</html>
